/*
 * Copyright 2015-2016 Tumblr, Inc.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.tumblr.backboard.example;

import com.facebook.rebound.Spring;
import com.facebook.rebound.SpringSystem;
import com.tumblr.backboard.Utils.MathUtils;
import com.tumblr.backboard.Utils.View;
import com.tumblr.backboard.performer.Performer;
import ohos.agp.components.Component;
import ohos.multimodalinput.event.MmiPoint;
import ohos.multimodalinput.event.TouchEvent;

/**
 * Scale an view with pinch zoom.
 *
 * @author ericleong
 * @since 2021-05-07
 */
public class ZoomFragment extends BaseFraction {
    private static final float ZOOM_MAX = 5.0f;

    private static final float ZOOM_MIN = 0.3f;

    private static final float ZOOM_DIFF = 0.05f;

    @Override
    public int getUiContent() {
        return ResourceTable.Layout_fragment_scale;
    }

    @Override
    public void initComponent() {
        final Component rect = mComponent.findComponentById(ResourceTable.Id_rect);

        final SpringSystem springSystem = SpringSystem.create();
        final Spring spring = springSystem.createSpring();

        spring.addListener(new Performer(rect, View.SCALE_X));
        spring.addListener(new Performer(rect, View.SCALE_Y));

        spring.setCurrentValue(1.0f, true);

        mComponent.setTouchEventListener(new Component.TouchEventListener() {
            float oldDist = 1.0f;
            float zoom = 0f; // 缩放比例
            @Override
            public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
                switch (touchEvent.getAction()) {
                    case TouchEvent.OTHER_POINT_DOWN:
                        zoom = 1.0f;
                        if (touchEvent.getPointerCount() == VALUE_TWO) {
                            oldDist = getFingerSpacing(touchEvent);
                        }
                        break;
                    case TouchEvent.POINT_MOVE:
                        if (touchEvent.getPointerCount() == VALUE_TWO) {
                            float newDist = getFingerSpacing(touchEvent);
                            if (newDist > oldDist) { // 放大
                                if (zoom < ZOOM_MAX) {
                                    zoom = MathUtils.floatToAdd(zoom, ZOOM_DIFF);
                                }
                            } else if (newDist < oldDist) { // 缩小
                                if (zoom > 0) {
                                    zoom = MathUtils.floatToSubtract(zoom, ZOOM_DIFF);
                                }
                            }
                            if (zoom < ZOOM_MIN) {
                                spring.setCurrentValue(1, true);
                            } else {
                                spring.setCurrentValue(zoom, true);
                            }
                            oldDist = newDist;
                        }
                        break;
                    case TouchEvent.OTHER_POINT_UP:
                        spring.setEndValue(1.0f);
                        break;
                    default:
                        break;
                }
                return true;
            }
        });
    }

    private float getFingerSpacing(TouchEvent touchEvent) {
        MmiPoint pointer = touchEvent.getPointerPosition(0);
        float px = pointer.getX();
        float py = pointer.getY();
        MmiPoint pointer1 = touchEvent.getPointerPosition(1);
        float px1 = pointer1.getX();
        float py1 = pointer1.getY();
        float pointerX = MathUtils.floatToSubtract(px, px1);
        float pointerY = MathUtils.floatToSubtract(py, py1);
        return (float) Math.sqrt(MathUtils.floatToAdd(pointerX * pointerX, pointerY * pointerY));
    }
}
